package model;



import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import utilities.Utilities;

public class AbstractChain {
	
	protected HashMap<Integer, Player> map;
	protected int activePlayerSeat;
	
	public AbstractChain(){
		map = new HashMap<Integer, Player>();
		activePlayerSeat = -1; // This will be initialized when the game starts.
	}
	
	public void initializeActivePlayer(int seat){
		this.activePlayerSeat = seat;
	}
	
	/**
	 * Returns the number of players left in the game
	 * @return
	 */
	public int size(){
		return map.size();
	}
	
	
	/**
	 * Add a player into the game. The seat number must be positive and
	 * the seat must be free.
	 * @param seat
	 * @param p
	 */
	public void addPlayer(int seat, Player p){		
		//check the seat is not taken and has a positive seat number
		if(map.get(seat) == null && seat > 0){
			map.put(seat, p);
		}
	}
	
	/**
	 * Get a reference to the player at the specified seat
	 * @param seat
	 * @return
	 */
	public Player getPlayer(int seat){
		return map.get(seat);
	}
	
	
	/**
	 * Remove the player in the specified seat from the game. If this player has the button then...?
	 * @param seat
	 */
	public void remove(int seat){			
		// Should not ever have 0 players once the game starts.
		if(map.size() == 1){
			System.out.println("ERROR: REMOVING LAST PLAYER IN GAME.");
		}
		
		// cant remove someone that is not there
		if(map.get(seat) != null){
			this.activePlayerSeat = getNextPlayer().getSeat();			
			map.remove(seat);			
		}
	}
	
	
	/**
	 * Get a reference to the next player. 
	 * @return
	 */
	public Player getNextPlayer(){
		Player current = map.get(activePlayerSeat);	
		
		Set<Integer> seats = map.keySet();
		Object[] seatsArray = seats.toArray();
		Arrays.sort(seatsArray);		
		
		this.activePlayerSeat = Utilities.getNextNumberInArray(activePlayerSeat, seatsArray);
		Player nextPlayer = map.get(activePlayerSeat);	
		return nextPlayer;
	}
	
	
	/**
	 * Get a reference to the previous player. This also passes the dealer button back
	 * @return
	 */
	public Player getPrevPlayer(){	
		Set<Integer> seats = map.keySet();
		Object[] seatsArray = seats.toArray();
		Arrays.sort(seatsArray);		
		
		this.activePlayerSeat = Utilities.getPrevNumberInArray(activePlayerSeat, seatsArray);
		return map.get(activePlayerSeat);
	}
	
	
	/** 
	 * Get a listing of the seat numbers in the game
	 * @return
	 */
	public Set<Integer> getSeatNumbers(){
		return map.keySet();
	}
	
	
	/**
	 * Get a listing of the players in the game
	 * @return
	 */
	public Collection<Player> getPlayers(){
		return map.values();
	}
	
	public Set<Map.Entry<Integer, Player>> entrySet(){
		return map.entrySet();
	}
	
	/**
	 * Get the seat number of the player with the dealer button
	 * @return
	 */
	public int getActivePlayerSeat(){
		return activePlayerSeat;
	}
	
	public void setActivePlayerSeat(int seat){
		this.activePlayerSeat = seat;
	}
	
	public Player getActivePlayer(){
		return map.get(activePlayerSeat);
	}
	
	
	/**
	 * Get a reference to the player with the dealer button
	 * @return
	 */
	public Player getDealerPlayer(){
		Player dealer = null;
		for(Player p : getPlayers()){
			if(p.hasButton()){
				dealer = p;
				break;
			}
		}
		return dealer;
	}
	
	/**
	 * Give the button to the player in the specified seat. If no one is sitting there then
	 * the button stays with whoever had it before.
	 * @param seat
	 */
	public void setDealerPlayer(int seat){
		// Make sure someone is in the specified seat
		Player p = map.get(seat);
		if(p != null){
			// Take the button from whoever hsa it
			for(Player takingIT : getPlayers()){
				takingIT.takeButton();
			}
			
			// Give the button to the player at the specified seat
			p.giveButton();
			System.out.println("Giving the dealer button to Player" + seat);
		}
	}
	
	/**
	 * this method is unreliable. DO not call it! Ever! (i do once. LOL damn)
	 * @return
	 */
	public int getBigBlindPlayerSeat(){
		int seat = -1;
		
		/// He is two after the dealer
		int dealerSeat = getDealerPlayer().getSeat();
		
		seat = Utilities.getNextNumberInArray(dealerSeat, getPlayers().toArray());
		seat = Utilities.getNextNumberInArray(seat, getPlayers().toArray());		
		
		return seat;
	}	
}
